import { compileToFunction } from './compiler/index.js';
import { initGlobalAPI } from './global-api/index.js';
import { initMixin } from './init'
import { lifeCycleMixin } from './lifecycle';
import { renderMixin } from './render';
import { createEle, patch } from './vdom/patch.js';


function Vue(options) {
  debugger;
  this._init(options)
}

initMixin(Vue);
renderMixin(Vue)
lifeCycleMixin(Vue)
initGlobalAPI(Vue)

// TODO:
// let vm1 = new Vue({
//   data() {
//     return {
//       name: 1
//     }
//   }
// })
// let render1 = compileToFunction(` <div>
// <li key="1">1</li>
// <li key="2">2</li>
// <li key="3">3</li>
// <li key="4">4</li>
// </div>`)

// let oldNode = render1.call(vm1)
// let el1 = createEle(oldNode);
// document.body.appendChild(el1)


// let vm2 = new Vue({
//   data() {
//     return {
//       name: 2
//     }
//   }
// })
// let render2 = compileToFunction(` <div>
// <li key="5" style="color: green">a</li>
// <li key="6">b</li>
// <li key="7" style="color: red">c</li>
// </div>`)


// let newNode = render2.call(vm2)

// setTimeout(() => {
//   patch(oldNode, newNode)
// }, 2000);
export default Vue;
// 响应式原理
// 1.new Vue 会调用_init方法进行初始化操作
// 2.会将用户的选项放到 vm.$options上
// 3.会对当前属性上搜素有没有data 数据   initState
// 4.有data 判断data是不是一个函数 ，如果是函数取返回值 initData
// 5.observe 去观测data中的数据 和 vm没关系，说明data已经变成了响应式
// 6.vm上像取值也能取到data中的数据 vm._data = data 这样用户能取到data了  vm._data
// 7.用户觉得有点麻烦 vm.xxx => vm._data
// 8.如果更新对象不存在的属性，会导致视图不更新， 如果是数组更新索引和长度不会触发更新
// 9.如果是替换成一个新对象，新对象会被进行劫持，如果是数组存放新内容 push unshift() 新增的内容也会被劫持
// 通过__ob__ 进行标识这个对象被监控过  （在vue中被监控的对象身上都有一个__ob__ 这个属性）
// 10如果你就想改索引 可以使用$set方法 内部就是splice()


// 更改数据视图的更新逻辑
//1.默认vue在初始化的时候 会对对象每一个属性都进行劫持，增加dep属性， 当取值的时候会做依赖收集
// 2.默认还会对属性值是（对象和数组的本身进行增加dep属性） 进行依赖收集
// 3.如果是属性变化 触发属性对应的dep去更新
// 4.如果是数组更新，触发数组的本身的dep 进行更新
// 5.如果取值的时候是数组还要让数组中的对象类型也进行依赖收集 （递归依赖收集）
// 6.如果数组里面放对象，默认对象里的属性是会进行依赖收集的，因为在取值时 会进行JSON.stringify操作